package com.nwpu.am.config;

import com.nwpu.am.constant.properties.ShiroProperties;
import com.nwpu.am.shiro.MyRealm;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.LinkedHashMap;

/**
 * ShiroConfig
 *
 * @author Roy
 * @version 1.0
 * {@code @date} 2024/6/5
 */

@Configuration
@Slf4j
public class ShiroConfig {
    @Resource
    private ShiroProperties shiroProperties;

    @Bean
    public HashedCredentialsMatcher credentialsMatcher(){
        log.info("创建凭证匹配器。。。");
        // 凭证匹配器
        HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher();
        // 设置加密算法和迭代次数
        credentialsMatcher.setHashAlgorithmName(shiroProperties.getHashAlgorithmName());
        credentialsMatcher.setHashIterations(shiroProperties.getHashIterations());
        return credentialsMatcher;
    }

    @Bean
    public Realm realm(MyRealm myRealm, HashedCredentialsMatcher credentialsMatcher) {
        log.info("创建realm域。。。");
        myRealm.setCredentialsMatcher(credentialsMatcher);
        return myRealm;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(Realm realm) {
        log.info("创建安全管理器。。。");
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 给安全管理器设置Realm
        securityManager.setRealm(realm);
        return securityManager;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        log.info("配置shiro过滤器工厂类。。。");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 注入安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/common/login");
        /*
            设置过滤器链，配置资源路径和权限认证方式

            默认情况下 Shiro 会拦截所有的请求，并要求用户进行认证（登录）

            anon:无需认证就可以访问
            authc:必须认证了才能让问
            user:必须拥有记住我功能才能用
            perms:拥有对某个资源的权限才能访问
            role:拥有某个角色权限才能访问
         */

        // 创建过滤器链定义
        LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();

        // 静态资源放行

        /* swagger资源 */
        filterMap.put("/webjars/**", "anon");
        filterMap.put("/swagger-resources", "anon");
        filterMap.put("/v2/**", "anon");
        filterMap.put("/doc.html", "anon");
        // 设置登录接口，不需要认证
        filterMap.put("/common/login", "anon");
        // 其他接口都需要认证
        filterMap.put("/**", "authc");

        // 设置过滤器链
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

        return shiroFilterFactoryBean;
    }
}
